/**
 * Copyright 2010 Adam Ruggles.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package saig.engine.editors;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Transparency;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToggleButton;

import saig.engine.models.Flag;
import saig.engine.models.Model;
import saig.engine.models.Player;
import saig.engine.models.Sprite;
import saig.engine.models.enemies.Goomba;
import saig.engine.models.enemies.KoopaTroopa;
import saig.engine.models.enums.ModelType;
import saig.engine.models.interfaces.Colorable;
import saig.engine.models.interfaces.Flyable;
import saig.engine.resources.ImageLoader;


/**
 * Model selector pane for the Map Editor.
 * @author Adam
 * @version $Id$
 * 
 * Created on Aug 12, 2010 at 8:06:16 PM 
 */
public class ModelPane extends JPanel {
	/**
	 * Private TileButton class used to display and allow user interaction
	 * with a tile in the Tile Pane.
	 */
	private class ModelButton extends JToggleButton implements ActionListener {
		/**
		 * Serial Version UID.
		 */
		private static final long serialVersionUID = -8187026737276120024L;
		/**
		 * The tile for this tile button.
		 */
		private final Model model;
		/**
		 * Constructs a tile button.
		 * @param tile The tile to set this button to.
		 */
		public ModelButton(final Model model) {
			super();
			this.model = model;
			Image icon = model.getFrames()[model.getFrame()].getImage();
			setIcon(new ImageIcon(icon));
			setMargin(new Insets(2,2,2,2));
			addActionListener(this);
		}
		/**
		 * {@inheritDoc}
		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
		 */
		@Override
		public void actionPerformed(final ActionEvent e) {
			target = model;
			modelLabel.setText(target.getType().toString());
		}
	}
	/**
	 * Serial Version UID.
	 */
	private static final long serialVersionUID = 4018682907871968530L;
	/**
	 * The tile button panel.
	 */
	private JPanel buttonPanel = null;
	/**
	 * The label for the currently selected model.
	 */
	private JLabel modelLabel = null;
	/**
	 * The target model (currently selected).
	 */
	private transient Model target = null;
	/**
	 * Constructs the tile pane with a map of tiles.
	 * @param tileMap The map of tiles.
	 */
	public ModelPane() {
		setLayout(new BorderLayout());
		add(getModelButtonPanel(), BorderLayout.NORTH);
		add(getModelLabel(), BorderLayout.SOUTH);
	}
	/**
	 * Adds all the Goomba Buttons.
	 * @param buttonPanel The button panel.
	 * @param group The button group.
	 */
	private void addGoomba(final JPanel buttonPanel, final ButtonGroup group) {
		ModelButton modelButton = new ModelButton(new Goomba(null));
		buttonPanel.add(modelButton);
		group.add(modelButton);
		// Add Flying Goomba
		Model model = new Goomba(null);
		modelButton = new ModelButton(model);
		((Flyable) model).setWings(true);
		modelButton.setIcon(new ImageIcon(drawWings(model)));
		buttonPanel.add(modelButton);
		group.add(modelButton);
	}
	/**
	 * Adds the finishing flag to the buttons.
	 * @param buttonPanel The button panel.
	 * @param group The button group.
	 */
	private void addFinishFlag(final JPanel buttonPanel, final ButtonGroup group) {
		final Flag flag = new Flag(null);
		flag.setX(24); flag.setY(144);
		final ModelButton modelButton = new ModelButton(flag);
		final GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
			.getDefaultScreenDevice().getDefaultConfiguration();
		BufferedImage img = gc.createCompatibleImage(flag.getWidth(), flag.getHeight(), Transparency.BITMASK);
		final Graphics2D g = (Graphics2D) img.getGraphics();
		flag.doRender(g, 0, 0);
		g.dispose();
		modelButton.setIcon(new ImageIcon(img.getScaledInstance(16, 32, Image.SCALE_FAST)));
		buttonPanel.add(modelButton);
		group.add(modelButton);
	}
	/**
	 * Adds all the Koopa Troopa buttons.
	 * @param buttonPanel The button panel.
	 * @param group The button group.
	 */
	private void addKoopaTroopa(final JPanel buttonPanel, final ButtonGroup group) {
		// Add Green Koopa Troopa.
		Model model = new KoopaTroopa(null);
		((Colorable) model).setColor(Colorable.GREEN);
		ModelButton modelButton = new ModelButton(model);
		buttonPanel.add(modelButton);
		group.add(modelButton);
		// Add Green Flying Koopa Troopa.
		model = new KoopaTroopa(null);
		((Colorable) model).setColor(Colorable.GREEN);
		((Flyable) model).setWings(true);
		modelButton = new ModelButton(model);
		modelButton.setIcon(new ImageIcon(drawWings(model)));
		buttonPanel.add(modelButton);
		group.add(modelButton);
		// Add Blue Koopa Troopa.
		model = new KoopaTroopa(null);
		((Colorable) model).setColor(Colorable.BLUE);
		modelButton = new ModelButton(model);
		buttonPanel.add(modelButton);
		group.add(modelButton);
		// Add Flying BLUE Koopa Troopa.
		model = new KoopaTroopa(null);
		((Colorable) model).setColor(Colorable.BLUE);
		((Flyable) model).setWings(true);
		modelButton = new ModelButton(model);
		modelButton.setIcon(new ImageIcon(drawWings(model)));
		buttonPanel.add(modelButton);
		group.add(modelButton);
		// Add Red Koopa Troopa.
		model = new KoopaTroopa(null);
		((Colorable) model).setColor(Colorable.RED);
		modelButton = new ModelButton(model);
		buttonPanel.add(modelButton);
		group.add(modelButton);
		// Add Flying Red Koopa Troopa.
		model = new KoopaTroopa(null);
		((Colorable) model).setColor(Colorable.RED);
		((Flyable) model).setWings(true);
		modelButton = new ModelButton(model);
		modelButton.setIcon(new ImageIcon(drawWings(model)));
		buttonPanel.add(modelButton);
		group.add(modelButton);
		// Add Yellow Koopa Troopa.
		model = new KoopaTroopa(null);
		((Colorable) model).setColor(Colorable.YELLOW);
		modelButton = new ModelButton(model);
		buttonPanel.add(modelButton);
		group.add(modelButton);
		// Add Flying Yellow Koopa Troopa.
		model = new KoopaTroopa(null);
		((Colorable) model).setColor(Colorable.YELLOW);
		((Flyable) model).setWings(true);
		modelButton = new ModelButton(model);
		modelButton.setIcon(new ImageIcon(drawWings(model)));
		buttonPanel.add(modelButton);
		group.add(modelButton);
	}
	/**
	 * Draws wings on models.  Can't use the normal modeling frames.
	 * @param model The model to draw the wings on.
	 * @return An image of the model with the wings added.
	 */
	private Image drawWings(final Model model) {
		Sprite[] sprites = ImageLoader.getInstance().getSprites("enemies.png", 16, 32);
		GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
			.getDefaultScreenDevice().getDefaultConfiguration();
		Image srcImage = model.getFrames()[model.getFrame()].getImage();
		Image srcWings = sprites[112].getImage();
		final BufferedImage img = gc.createCompatibleImage(32, 32, Transparency.BITMASK);
		final Graphics2D g = (Graphics2D) img.getGraphics();
		if (model.getType() == ModelType.GOOMBA) {
			g.drawImage(srcWings, 19, -10, srcWings.getWidth(null) + 19, srcWings.getHeight(null) - 10,
					srcWings.getWidth(null), 0, 0, srcWings.getHeight(null), null);
			g.drawImage(srcImage, 8, 0, null);
			g.drawImage(srcWings, -3, -10, null);
		} else {
			//g.drawImage(srcImage, 7, 0, null);
			g.drawImage(srcImage, 8, 0, null);
			g.drawImage(srcWings, -1, -14, null);
		}
		g.dispose();
		return img;
	}
	/**
	 * Returns the tile button panel.
	 * @return The tile button panel.
	 */
	private JPanel getModelButtonPanel() {
		if (buttonPanel == null) {
			buttonPanel = new JPanel(new GridLayout(0, 3, 2, 2));
			final ButtonGroup group = new ButtonGroup();
			// Add the Player Model.
			target = new Player(null);
			ModelButton modelButton = new ModelButton(target);
			modelButton.setSelected(true);
			buttonPanel.add(modelButton);
			group.add(modelButton);
			// Add Goomba.
			addGoomba(buttonPanel, group);
			// Add Koopa Troopa
			addKoopaTroopa(buttonPanel, group);
			// Add the flag.
			addFinishFlag(buttonPanel, group);
		}
		return buttonPanel;
	}
	/**
	 * Returns the selected tile label.
	 * @return The selected tile label.
	 */
	private JLabel getModelLabel() {
		if (modelLabel == null) {
			if (target == null) {
				modelLabel = new JLabel("N/A", JLabel.CENTER);
			} else {
				modelLabel = new JLabel(target.getType().toString(), JLabel.CENTER);
			}
			modelLabel.setFont(new Font("San-Serif", Font.BOLD, 20));
		}
		return modelLabel;
	}
	/**
	 * Returns target.
	 * @return the target.
	 */
	public Model getTarget() {
		return target;
	}
}
